package edu.fudan.p2p.chord;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class ChordSimulation {
    private static int fingerTableSize;
    public static int networkSize;
    private static Map<Integer, Node> networks;

    public ChordSimulation (int size) {
        this.fingerTableSize = size;
    }

    public void read(String fileName) throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)));
        String line;
        int nodeID = -1;
        int newAddID = -1;
        while((line = reader.readLine()) != null){
            String[] strs= line.trim().split(" ");
            String action = strs[0];
            String parameter = strs[1];
            if (action.equals("init")) {
                int networkSize = Integer.parseInt(parameter);
                init(networkSize);
            } else if (action.equals("addpeer")) {
                nodeID = Integer.parseInt(parameter);
                newAddID = nodeID;
                addPeer(nodeID, fingerTableSize);
            } else if (action.equals("removepeer")) {
                nodeID = Integer.parseInt(parameter);
                remove(nodeID);
            } else if (action.equals("insert")) {
                insertValue(newAddID, parameter);
            } else if (action.equals("print")) {
                int key = Integer.parseInt(parameter);
                print(newAddID, key);
            } else if (action.equals("find")) {
                int key = Integer.parseInt(parameter);
                find(0, key);
            }
        }
    }

    private void print(int newAddID, int key) {
        Node node = networks.get(newAddID);
        node.print(key);
    }

    private void insertValue(int nodeID, String value) {
        Node node = networks.get(nodeID);
        node.insert(value);
    }

    private void addPeer(int nodeID, int fingerTableSize) {
        Node node = new Node(networks, nodeID, fingerTableSize);
    }

    private void remove(int nodeID) {
        Node node = networks.get(nodeID);
        node.remove();
    }

    private void find(int nodeID, int key) {
        Node node = networks.get(nodeID);
        node.find(key);
    }

    private void init(int networkSize) {
        this.networkSize = networkSize;
        networks = new HashMap<Integer, Node>();
    }

    public static int hash(String str) {
        int key = 1;
        int count = 0;
        for(char c : str.toCharArray()) {
            count = count + 1;
            key = key * 2;
            key = key + c * count;
        }
        return key % networkSize;
    }

    public static void main(String[] args) throws IOException {
        if (args.length != 2) {
            System.out.println("Usage: java ChordSimulation filename size");
            System.exit(0);
        }
        String fileName = args[0];
        int size = Integer.parseInt(args[1]);
        ChordSimulation cs = new ChordSimulation(size);
        cs.read(fileName);
    }
}
